<script setup lang="ts">
import type { TableColumnCtx, TableInstance } from 'element-plus'
import { ElTable } from 'element-plus'
import SCode from '@/components/common/SCode.vue'
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import SFilterFormItem from '@/components/common/list/SFilterFormItem.vue'

const props = withDefaults(
  defineProps<{
    statement: any
    total: number
    pageSize: number
    data: any
    methods: any
    rowKey?: string
    tableLoading: boolean
    isSelection: boolean
    topButtonShow: boolean
    rowButtonShow: boolean
  }>(),
  {
    isSelection: false,
    topButtonShow: true,
    rowButtonShow: true,
    rowKey: '',
    methods: {}
  }
)

const multipleTableRef = ref<TableInstance>()
const emit = defineEmits(['search', 'handleSelectionChange'])
const filter = ref<any>({})
const sortRules = ref<any>({})
const selection = ref<any[]>([])

const route = useRoute()
const rowButton = route.meta.rowButton
const topButton = route.meta.topButton

const expand = ref<boolean>()
const currentPage = ref<number>()

watch(
  () => props.statement,
  (newIt, oldIt) => {
    if (oldIt === undefined) {
      newIt.mateForm.forEach((item: any) => {
        item.forEach((it: any) => {
          if (filter.value[it.property] === undefined) {
            if (it.type === 'select') {
              filter.value[it.property] = { operator: 'EQ' }
            } else if (it.type === 'date' || it.type === 'datetime' || it.type === 'time') {
              filter.value[it.property] = { operator: 'EQ' }
            } else {
              filter.value[it.property] = { operator: 'EQ' }
            }
          }
        })
      })
    }
  }
)

function checkExpand() {
  expand.value = !expand.value
}

function search() {
  const orderList = Object.entries(sortRules.value)
    .map(([field, direction]) => {
      return { field, direction }
    })
    .filter((it) => it.direction !== null)
  emit('search', filter.value, orderList, currentPage.value)
}

function sortChange(data: { column: TableColumnCtx<any>; prop: string; order: any }) {
  if (data.column.sortable === 'custom') {
    sortRules.value[data.prop] = data.order
    search()
  }
}

function currentChange(current: number) {
  currentPage.value = current
  search()
}

const handleSelectionChange = (val: any[]) => {
  selection.value = val
  emit('handleSelectionChange', val)
}

const toggleSelection = (rows: any[], selected: boolean) => {
  if (rows) {
    rows.forEach((row) => {
      multipleTableRef.value!.toggleRowSelection(row, selected)
    })
  } else {
    multipleTableRef.value!.clearSelection()
  }
}

defineExpose({
  toggleSelection,
  selection
})
</script>

<template>
  <div v-if="props.statement === undefined" class="skeleton-container">
    <!-- Filter card skeleton -->
    <el-card class="skeleton-card">
      <el-skeleton :rows="3" animated />
    </el-card>

    <!-- Table skeleton -->
    <el-card class="skeleton-table">
      <el-skeleton :rows="6" animated :throttle="500" />
    </el-card>

    <!-- Pagination skeleton -->
    <div class="skeleton-pagination">
      <el-skeleton-item variant="button" style="width: 100px; height: 32px" />
    </div>
  </div>
  <template v-else>
    <el-card
      v-if="
        statement !== undefined && statement.mateForm !== undefined && statement.mateForm.length > 0
      "
      class="s-card"
    >
      <el-row :gutter="20">
        <el-col :span="23">
          <el-form :inline="true" :label-width="80" label-position="left">
            <el-form-item :label="it.label" v-for="it in statement.mateForm[0]" :key="it.property">
              <slot :name="'fm-' + it.property" :mate="it" :formItem="filter![it.property]">
                <s-filter-form-item :mate="it" :form="filter" />
              </slot>
            </el-form-item>

            <el-form-item>
              <el-button icon="Search" @click="search" type="primary" class="action-button"
                >搜索
              </el-button>
            </el-form-item>
          </el-form>
        </el-col>

        <!-- 展开/收起按钮 -->
        <el-col
          v-if="statement.mateForm.length > 1"
          :span="1"
          style="display: flex; justify-content: end"
        >
          <el-button @click="checkExpand" text :icon="expand ? 'ArrowDown' : 'ArrowLeft'" />
        </el-col>
      </el-row>

      <!-- 展开后显示的其他表单项 -->
      <el-collapse-transition>
        <div v-show="expand">
          <el-form :label-width="80" label-position="left">
            <template v-for="(it, index) in statement.mateForm" :key="index">
              <template v-if="index !== 0">
                <el-form-item v-if="it.length === 1" :label="it[0].label">
                  <slot
                    :name="'fm-' + it[0].property"
                    :mate="it"
                    :formItem="filter![it[0].property]"
                  >
                    <s-filter-form-item :mate="it[0]" :form="filter" />
                  </slot>
                </el-form-item>

                <el-form inline v-else :label-width="80" label-position="left">
                  <el-form-item v-for="ec in it" :key="ec.property" :label="ec.label">
                    <slot :name="'fm-' + ec.property" :mate="ec" :formItem="filter![ec.property]">
                      <s-filter-form-item :mate="ec" :form="filter" />
                    </slot>
                  </el-form-item>
                </el-form>
              </template>
            </template>
          </el-form>
        </div>
      </el-collapse-transition>
    </el-card>

    <div class="s-button-list">
      <slot name="button-top-append-prev"></slot>

      <slot name="button-top-route" v-if="topButtonShow">
        <el-button
          v-for="it in topButton"
          :type="it.btnType || 'primary'"
          :icon="it.icon === '#' ? '' : it.icon"
          :key="it.menuId"
          size="default"
          class="action-button"
          @click.stop="props.methods[it.component!]()"
        >
          {{ it.menuName }}
        </el-button>
      </slot>

      <slot name="button-top-append-after"></slot>
    </div>

    <el-table
      ref="multipleTableRef"
      v-loading="tableLoading"
      v-if="statement !== undefined && statement.mateList !== undefined"
      class="s-list-table"
      stripe
      @sort-change="sortChange"
      highlight-current-row
      :row-key="props.rowKey"
      :data="data"
      @selection-change="handleSelectionChange"
    >
      <el-table-column v-if="isSelection" type="selection" :reserve-selection="true" width="55" />
      <template v-for="it in statement.mateList" :key="it.property">
        <el-table-column
          v-if="it.visible === undefined ? true : it.visible"
          :property="it.property"
          :width="it.width"
          :label="it.label"
          :sortable="it.sortable"
        >
          <template #default="scope">
            <slot :name="'tb-' + it.property" :row="scope.row" :column="scope.column">
              <span
                v-if="it.codeType === undefined || it.codes == undefined"
                v-text="scope.row[it.property]"
              />
              <s-code
                v-else
                :codes="it.codes"
                :code-type="it.codeType!"
                :code-key="scope.row[it.property]"
              />
            </slot>
          </template>
        </el-table-column>
      </template>
      <slot name="button-row-route">
        <el-table-column property="action" v-if="rowButtonShow && rowButton != null && rowButton.length !== 0" label="操作">
          <template #default="scope">
            <el-button
              v-for="it in rowButton"
              :type="it.btnType || 'primary'"
              :icon="it.icon === '#' ? '' : it.icon"
              :key="it.menuId"
              size="small"
              link
              class="action-button"
              @click.stop="props.methods[it.component!](scope.row)"
            >
              {{ it.menuName }}
            </el-button>
          </template>
        </el-table-column>
      </slot>
    </el-table>
    <el-pagination
      class="s-pagination"
      background
      layout="prev, pager, next"
      @current-change="currentChange"
      :page-size="props.pageSize"
      :total="props.total"
    />
  </template>
</template>

<style scoped>
.s-button-list {
  margin: 20px 0;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.s-card {
  border-radius: 0;
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
  transition: box-shadow 0.2s ease;
  margin-bottom: 20px;
  border: none;
}

:deep(.el-card__header) {
  padding: 16px 20px;
  background: linear-gradient(90deg, var(--el-color-primary-light-9), transparent);
  border-bottom: 1px solid var(--el-border-color-lighter);
}

:deep(.el-card__body) {
  padding: 20px;
}

:deep(.el-form-item) {
  margin-bottom: 20px;
}

:deep(.el-form-item__label) {
  font-weight: 500;
  color: var(--el-text-color-primary);
}

.s-list-table {
  width: 100%;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

:deep(.el-table) {
  --el-table-border-color: var(--el-border-color-lighter);
  --el-table-header-bg-color: var(--el-fill-color-light);
}

:deep(.el-table th) {
  background: var(--el-fill-color-light);
  font-weight: 600;
  color: var(--el-text-color-primary);
}

:deep(.el-table .el-button) {
  margin: 0 4px;
  border: none;
  background: transparent;
}

:deep(.el-table .el-button.link) {
  color: var(--el-color-primary);
  transition: color 0.2s ease;
}

.action-button {
  border-radius: 6px;
  font-weight: 500;
  transition: all 0.2s ease;
}

:deep(.el-table .el-button.link:focus) {
  border: none !important;
  background: transparent !important;
}

.el-pagination {
  margin-top: 20px;
  justify-content: flex-end;
}

@media (max-width: 768px) {
  .s-button-list {
    justify-content: center;
  }

  :deep(.el-form-item__label) {
    font-size: 14px;
  }

  :deep(.el-card__header) {
    padding: 12px 16px;
  }

  :deep(.el-card__body) {
    padding: 16px;
  }

  :deep(.el-table .el-button) {
    margin: 2px;
    font-size: 12px;
  }
}

/* Skeleton styles */
.skeleton-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.skeleton-card {
  border-radius: 8px;
  box-shadow: none;
  border: none;
}

.skeleton-buttons {
  display: flex;
  gap: 12px;
  margin: 20px 0;
}

.skeleton-table {
  border-radius: 8px;
  box-shadow: none;
  overflow: hidden;
  border: none;
}

.skeleton-pagination {
  display: flex;
  justify-content: flex-end;
  margin-top: 20px;
}

:deep(.skeleton-card .el-card__body),
:deep(.skeleton-table .el-card__body) {
  padding: 20px;
}

:deep(.el-skeleton) {
  --el-skeleton-color: var(--el-fill-color-light);
  --el-skeleton-to-color: var(--el-fill-color-lighter);
}

:deep(.el-skeleton__item) {
  border-radius: 4px;
}
</style>
